package com.demo.websocket.controller;

import java.util.Date;
import java.util.concurrent.CopyOnWriteArraySet;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.SimpMessageType;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.simp.annotation.SendToUser;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.demo.websocket.config.SocketSessionRegistry;
import com.demo.websocket.domain.RequestMessage;
import com.demo.websocket.domain.ResponseMessage;
import com.demo.websocket.domain.UserClient;

//-------------------------------------------------
//重点：  想要使用一对发送，比如sendToUser,只要涉及到user的，前端订阅路径前必须加/user，
//例如/user/topic/greetings
//-------------------------------------------------

//@SendTo("/topic/greetings") // 给所有订阅此主题的用户发送，即多人
// @SendToUser("/topic/greetings")//给所有发起请求的用户发送，即一个人
// broadcast=false,只给一个sessionid发送(多浏览器会存在多sessionid),默认为true

@Controller
public class WsController {

	/** session操作类 */
	@Autowired
	SocketSessionRegistry webAgentSessionRegistry;
	/** 消息发送工具 */
	@Autowired
	private SimpMessagingTemplate template;

	/**
	 * 发送到所有这个主题的用户
	 */
	@MessageMapping("/sendto")
	@SendTo("/topic/greetings")
	public ResponseMessage sendTo(RequestMessage message) {
		System.err.println("sendto:" + message);
		return new ResponseMessage(message.getFrom(), message.getTo(), message.getMessage(), new Date());
	}

	/**
	 * 发送到发起请求的用户
	 */
	@MessageMapping("/sendtouser")
	@SendToUser(value = "/topic/greetings", broadcast = false)
	public ResponseMessage sendToUser(RequestMessage message) {
		System.err.println("sendtouser:" + message);
		return new ResponseMessage(message.getFrom(), message.getTo(), message.getMessage(), new Date());
	}

	/**
	 * 给指定主题的指定用户发消息,http请求
	 */
	@GetMapping(value = "/sendall")
	@ResponseBody
	// @MessageMapping("/sendall")
	public ResponseMessage SendToCommUserMessage(RequestMessage message) {
		System.err.println("sendall_http:" + message);
		CopyOnWriteArraySet<UserClient> allSessionIds = webAgentSessionRegistry.getAllSessionIds();
		for (UserClient userClient : allSessionIds) {
			String sessionId = userClient.getSessionId();
			template.convertAndSendToUser(sessionId, "/topic/greetings",
					new ResponseMessage(message.getFrom(), message.getTo(), message.getMessage(), new Date()),
					createHeaders(sessionId));
		}
		return new ResponseMessage(message.getFrom(), message.getTo(), message.getMessage(), new Date());
	}

	/**
	 * 根据用户key发送消息 发送消息 只不过是ws版本 http请求不能访问
	 * 
	 * 
	 * @param message
	 * @return
	 * @throws Exception
	 */
	@MessageMapping("/sendone")
	public void senMessageToSingle(RequestMessage message) throws Exception {
		System.err.println("sendone:" + message);
		// 这里没做校验
		CopyOnWriteArraySet<UserClient> allSessionIds = webAgentSessionRegistry.getAllSessionIds();
		for (UserClient userClient : allSessionIds) {
			if (userClient.getName().equals(message.getTo())) {
				String sessionId = userClient.getSessionId();
				System.out.println(sessionId);
				template.convertAndSendToUser(sessionId, "/topic/greetings",
						new ResponseMessage(message.getFrom(), message.getTo(), message.getMessage(), new Date()),
						createHeaders(sessionId));
				System.out.println("success");
			}
		}

	}

	private MessageHeaders createHeaders(String sessionId) {
		SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
		headerAccessor.setSessionId(sessionId);
		headerAccessor.setLeaveMutable(true);
		return headerAccessor.getMessageHeaders();
	}

}
